﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApiTest.Dto.System;
using WebApiTest.Dto.Utils;
using WebApiTest.Models;
using WebApiTest.Utils;

namespace WebApiTest.Service.System
{
    public class RoleService
    {
        officeContext db = new officeContext();

        public TableRspDTO list4Table(TableReqDTO tableReqDTO)
        {
            long count = db.SystemRole.Where(role=>string.IsNullOrEmpty(tableReqDTO.parseQueryParam("name")) 
            || role.RoleName.Contains(tableReqDTO.parseQueryParam("name"))).LongCount();
            List<JObject> res = db.SystemRole
                .Select(r => new { key = r.RoleId, id = r.RoleId, name = r.RoleName, describe = r.RoleInfo, createTime = r.GmtCreate })
                .Where(role => string.IsNullOrEmpty(tableReqDTO.parseQueryParam("name"))
            || role.name.Contains(tableReqDTO.parseQueryParam("name")))
                .OrderByDescending(r => r.id)
                .Skip(tableReqDTO.getStart())
                .Take(tableReqDTO.pageSize)
                .ToList()
                .ConvertAll(r => JObject.FromObject(r));
            PagingDTO pagingDTO = new PagingDTO(
                tableReqDTO.pageNo,
                tableReqDTO.pageSize,
                count,
                res
                );
            return new TableRspDTO(pagingDTO);
        }

        public int add(RoleDTO roleDTO)
        {
            SystemRole role = new SystemRole();
            role.RoleName = roleDTO.name;
            role.RoleInfo = roleDTO.describe;
            role.GmtCreate = DateTime.Now;
            db.SystemRole.Add(role);
            db.SaveChanges();
            return 1;
        }

        public int update(RoleDTO roleDTO)
        {
            SystemRole role = db.SystemRole.Find(roleDTO.id);
            role.RoleName = roleDTO.name;
            role.RoleInfo = roleDTO.describe;
            db.SaveChanges();
            return 1;
        }

        public int remove(string ids)
        {
            List<SystemRole> list = new List<SystemRole>();
            string[] idList = ids.Split(",");
            foreach(string id in idList)
            {
                list.Add(db.SystemRole.Find(long.Parse(id)));
            }
            db.SystemRole.RemoveRange(list);
            //更新到数据库
            db.SaveChanges();
            return list.Count();
        }

        public List<PermissionDTO> listPermissionByRoleId(long roleId)
        {
            return db.SystemPermission.Join(db.SystemMenu, p => p.MenuId, m => m.MenuId, (p, m) => 
            new PermissionDTO { roleId = p.RoleId.ToString(), permissionId = m.MenuCode, permissionName = m.MenuName, actionList = m.MenuType.ToString(), dataAccess = m.MenuStatus.ToString() })
                .Where(o => o.roleId == roleId.ToString())
                .Where(o => o.dataAccess.Equals("0"))
                .ToList();
        }

        public List<PermissionDTO> listPermission4Tree(long roleId)
        {
            return db.SystemPermission.Join(db.SystemMenu, p => p.MenuId, m => m.MenuId, (p, m) =>
            new PermissionDTO { roleId = m.MenuId.ToString(), permissionId = m.MenuCode, permissionName = m.MenuName, actionList = m.MenuType.ToString(), actions = p.RoleId.ToString(), dataAccess = m.MenuStatus.ToString() })
                .Where(o => o.actions == roleId.ToString())
                .Where(o => o.dataAccess.Equals("0"))
                .ToList(); 
        }

        public RoleDTO getRoleByRoleId(long roleId)
        {
            var res = db.SystemRole.Where(per => per.RoleId == roleId).ToList();
            if(res.Count == 0)
            {
                return null;
            }
            else
            {
                return ConvertUtil.ConvertModel<RoleDTO, SystemRole>(res[0]);
            }
        }

        public List<TreeDTO> listPermissionByRoleId4Tree(long roleId)
        {
            List<PermissionDTO> list = listPermission4Tree(roleId);
            List<TreeDTO> res = new List<TreeDTO>();
            TreeDTO treeDTO;
            foreach(PermissionDTO permission in list)
            {
                treeDTO = new TreeDTO();
                if(permission.actionList.Equals("1"))
                {
                    treeDTO.key = int.Parse(permission.roleId);
                    treeDTO.isLeaf = 1;
                    res.Add(treeDTO);
                }
                else
                {
                    treeDTO.key = int.Parse(permission.roleId);
                    treeDTO.isLeaf = 2;
                    res.Add(treeDTO);
                }
            }
            return res;
        }

        public List<TreeDTO> listPermission4Tree()
        {
            TreeDTO treeDTO;
            List<TreeDTO> listTreeTwo;
            List<TreeDTO> listTreeOne = new List<TreeDTO>();
            List<PermissionDTO> listPermissionDto = db.SystemMenu
                .Select(e => new PermissionDTO { roleId = e.MenuId.ToString(), permissionId = e.MenuCode, permissionName = e.MenuName, actions = e.MenuFather.ToString(), actionList = e.MenuType.ToString(), dataAccess = e.MenuStatus.ToString() })
                .Where(o => o.dataAccess.Equals("0"))
                .OrderBy(e => e.roleId)
                .ToList();
            foreach (PermissionDTO permission in listPermissionDto)
            {
                if("1".Equals(permission.actionList))
                {
                    listTreeTwo = new List<TreeDTO>();
                    foreach (PermissionDTO permissionDTO in listPermissionDto)
                    {
                        if(permissionDTO.actions.Equals(permission.roleId))
                        {
                            treeDTO = new TreeDTO();
                            treeDTO.title = permissionDTO.permissionName;
                            treeDTO.key = int.Parse(permissionDTO.roleId);
                            listTreeTwo.Add(treeDTO);
                        }
                    }
                    treeDTO = new TreeDTO();
                    treeDTO.title = permission.permissionName;
                    treeDTO.key = int.Parse(permission.roleId);
                    treeDTO.children = listTreeTwo;
                    listTreeOne.Add(treeDTO);
                }
            }
            return listTreeOne;
        }

        public int authorize(JObject request)
        {
            long roleId = long.Parse(request["roleId"].ToString());
            string menuIds = request["menuIds"].ToString();
            List<SystemPermission> systemPermissions = db.SystemPermission.Where(p => p.RoleId.Equals(roleId)).ToList();
            db.SystemPermission.RemoveRange(systemPermissions);
            string[] ids = menuIds.Split(",");
            foreach(string id in ids)
            {
                if(!"".Equals(id))
                {
                    SystemPermission systemPermission = new SystemPermission();
                    systemPermission.RoleId = roleId;
                    systemPermission.MenuId = long.Parse(id);
                    systemPermission.GmtCreate = DateTime.Now;
                    db.Add(systemPermission);
                }
            }
            db.SaveChanges();
            return ids.Length;
        }

        public List<RoleDTO> listRole()
        {
            return db.SystemRole.Select(r => new RoleDTO { id = r.RoleId, name = r.RoleName, describe = r.RoleInfo, createTime = (DateTime)r.GmtCreate }).ToList();
        }

    }
}
